package cn.com.callback

import cn.com.elite.EliteBean
import cn.com.elite.Util
import cn.com.kh.AllotUtil
import cn.com.kh.KHDBConfig
import cn.com.kh.KHUtil
import jdk.internal.org.objectweb.asm.TypeReference
import net.sf.json.JSONArray
import org.json.JSONObject
import org.apache.xmlbeans.impl.xb.xsdschema.ListDocument
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.jdbc.core.JdbcTemplate

import java.util.concurrent.ConcurrentHashMap

/**
 * 华盛通回收用户再分配
 */

public class autoHSTReuserIssueRule implements CallBackInvoke {
    private static final Logger log = LoggerFactory.getLogger(autoHSTReuserIssueRule.class);

    public void doCallBack(EliteBean eliteBean, String callBack, Map map, String paramString) {
        JdbcTemplate jt = new JdbcTemplate(eliteBean.getDataSource()); // 获取数据源

        List<Map<String, Object>> reuserRuleList = jt.queryForList("SELECT rule_id, issue_userno, issue_range, issue_priority1, issue_priority2, issue_priority3, weight, issue_style, rolegroup_id, staff_id FROM hst_reuser_rule_issue WHERE 1 = 1 AND rule_state = 1 AND DATE_FORMAT( rule_startdate, '%Y-%m-%d' ) <= DATE_FORMAT( NOW(), '%Y-%m-%d' ) AND DATE_FORMAT( rule_enddate, '%Y-%m-%d' ) >= DATE_FORMAT( NOW(), '%Y-%m-%d' ) AND CASE WHEN issue_frequency = '小时' AND DATE_FORMAT( DATE_ADD( last_date, INTERVAL 1 HOUR ), '%Y-%m-%d %H' ) <= DATE_FORMAT( NOW(), '%Y-%m-%d %H' ) THEN 1 WHEN issue_frequency = '天' AND DATE_FORMAT( DATE_ADD( last_date, INTERVAL 1 DAY ), '%Y-%m-%d %H' ) <= DATE_FORMAT( NOW(), '%Y-%m-%d %H' ) THEN 1 WHEN issue_frequency = '周' AND DATE_FORMAT( DATE_ADD( last_date, INTERVAL 1 WEEK ), '%Y-%m-%d %H' ) <= DATE_FORMAT( NOW(), '%Y-%m-%d %H' ) THEN 1 WHEN issue_frequency = '月' AND DATE_FORMAT( DATE_ADD( last_date, INTERVAL 1 MONTH ), '%Y-%m-%d %H' ) <= DATE_FORMAT( NOW(), '%Y-%m-%d %H' ) THEN 1 WHEN issue_frequency = '季' AND DATE_FORMAT( DATE_ADD( last_date, INTERVAL 1 QUARTER ), '%Y-%m-%d %H' ) <= DATE_FORMAT( NOW(), '%Y-%m-%d %H' ) THEN 1 WHEN issue_frequency = '年' AND DATE_FORMAT( DATE_ADD( last_date, INTERVAL 1 YEAR ), '%Y-%m-%d %H' ) <= DATE_FORMAT( NOW(), '%Y-%m-%d %H' ) THEN 1 ELSE '' END = 1 ORDER BY order_adjustment ");
        log.debug("回收用户分配规则集合:" + reuserRuleList);

        for (int a = 0; a < reuserRuleList.size(); a++) {
            try {

                String rule_id = reuserRuleList.get(a).get("rule_id").toString(); //规则主键
                String issue_userno = reuserRuleList.get(a).get("issue_userno").toString(); //每频次分配用户总量
                String issue_range = reuserRuleList.get(a).get("issue_range").toString(); //分配数据范围id
                String dealcont = "规则执行情况：";
                Map<String, String> assignMap = new HashMap<String, String>(); //规则执行情况集合

                if (!KHUtil.isNull(issue_range)) {

                    String sqlPartSQL = '''Select Ifnull(Where_Sql, '') As Where_Sql, If((Order_Sql Is Null Or Order_Sql = ''), '', Concat('Order By Case ', Order_Sql, ' ELSE 9999 END ')) As Order_Sql
    From (Select Concat(' and ', Concat('(', Group_Concat(Where_Sql Separator ' or '), ')')) As Where_Sql, Group_Concat(Concat('when 1=1 and ', Where_Sql, ' then ', Level_Id) Separator '  ') As Order_Sql
          From (Select Level_Id, Concat('(', Group_Concat(Where_Sql Separator ' and '), ')') As Where_Sql
                  From (Select Level_Id, Group_Concat(R1.Remark Separator ' ') As Where_Sql, Group_Concat(R1.Remark Separator ' ') As Order_Sql, Level, Countnum
                          From (Select Concat(Case When Countnum > 1 Then Concat('(', R1.Remark, ')') Else R1.Remark End) As Remark, Level, Countnum, 1 As Level_Id
                                  From (Select R2.Level, Count(*) As Countnum, Group_Concat(R2.Parentpath Separator ' or ') As Remark
                                          From Hst_Reuser_Rule_Issue R1
                                          Left Join (Select * From c_Codetables Where Use_Type = '回收用户再分配-优先级' And Use_Status = '1') R2 On Find_In_Set(R2.Code_Id, R1.Issue_Priority1) > 0
                                         Where Rule_Id = \'''' + rule_id + '''\'
                                         Group By R2.Level) R1
                                Union All
                                Select Concat(Case When Countnum > 1 Then Concat('(', R1.Remark, ')') Else R1.Remark End) As Remark,
                                       Level,
                                       Countnum,
                                       2 As Level_Id
                                  From (Select R2.Level, Count(*) As Countnum, Group_Concat(R2.Parentpath Separator ' or ') As Remark
                                          From Hst_Reuser_Rule_Issue R1
                                          Left Join (Select * From c_Codetables Where Use_Type = '回收用户再分配-优先级' And Use_Status = '1') R2 On Find_In_Set(R2.Code_Id, R1.Issue_Priority2) > 0
                                         Where Rule_Id = \'''' + rule_id + '''\'
                                         Group By R2.Level) R1
                                Union All
                                Select Concat(Case When Countnum > 1 Then Concat('(', R1.Remark, ')') Else R1.Remark End) As Remark,
                                       Level,
                                       Countnum,
                                       3 As Level_Id
                                  From (Select R2.Level, Count(*) As Countnum, Group_Concat(R2.Parentpath Separator ' or ') As Remark
                                          From Hst_Reuser_Rule_Issue R1
                                          Left Join (Select * From c_Codetables Where Use_Type = '回收用户再分配-优先级' And Use_Status = '1') R2 On Find_In_Set(R2.Code_Id, R1.Issue_Priority3) > 0
                                         Where Rule_Id = \'''' + rule_id + '''\'
                                         Group By R2.Level) R1) R1
                         Group By Level_Id, Level, Countnum) R1
                 Group By Level_Id) R1
        ) R1''';

                    List SqlList = eliteBean.chaxun_sql(sqlPartSQL, "dataSource");
                    String where_sql = "";
                    String order_sql = "";
                    if (SqlList.size() > 0) {
                        where_sql = SqlList.get(0).get("where_sql");
                        order_sql = SqlList.get(0).get("order_sql");
                    }
                    log.debug("where_sql：" + where_sql + "  order_sql：" + order_sql);

                    JSONArray weightlist = JSONArray.fromObject(reuserRuleList.get(a).get("weight").toString()); //权重
                    String issue_style = reuserRuleList.get(a).get("issue_style").toString(); //分配方式
                    String rolegroup_id = reuserRuleList.get(a).get("rolegroup_id").toString();  //分配组
                    String staff_id = reuserRuleList.get(a).get("staff_id").toString();//分配人
                    int issue_usernoi = Integer.parseInt(issue_userno); //每频次分配用户总量转为int类型

                    Map<String, String> weightmap = new HashMap<>();
                    for (int b = 0; b < weightlist.size(); b++) {
                        //JSONObject obj = weightlist.getJSONObject(b);
                        JSONObject obj = new JSONObject(weightlist.getJSONObject(b));
                        String id = obj.getString("id");
                        String no = obj.getString("proportion");
                        weightmap.put(id, no);
                    }

                    //集合：坐席id,坐席对应的任务量
                    List<List<String>> resUsers = new ArrayList<>();

                    if (issue_style.equals("staff")) {
                        //根据权重计算每个坐席的任务量
                        resUsers = AllotUtil.getAllotNum(weightmap, issue_usernoi, "权重");
                        for (List<String> resUser : resUsers) {
                            resUser.add("0");
                        }
                        log.debug("resUsers_staff:" + resUsers);
                    } else if (issue_style.equals("rolegroup")) {
                        //根据权重计算每个组的任务量
                        List<List<String>> resgroups = AllotUtil.getAllotNum(weightmap, issue_usernoi, "权重");
                        log.debug("根据权重计算每个组的任务量:" + resgroups);

                        //集合：组别内的所有坐席id,坐席对应的任务数
                        List<List<String>> groupresUsers = new ArrayList<>();
                        for (int c = 0; c < resgroups.size(); c++) {
                            String groupid = resgroups.get(c).get(0).toString();
                            String staffCheckSQL = "SELECT DISTINCT r1.staff_id FROM staffrolegroup r1 LEFT JOIN staff r2 ON r1.STAFF_ID = r2.STAFF_ID WHERE r2.WORKSTATUS = 'ONLINE' AND r1.rolegroup_id = '" + groupid + "'";
                            List stafflist = eliteBean.chaxun_sql(staffCheckSQL, "dataSource");

                            List stafflist2 = new ArrayList();
                            for (int x = 0; x < stafflist.size(); x++) {
                                String staff_id_temp = stafflist.get(x).get("staff_id").toString();
                                stafflist2.add(staff_id_temp);

                            }
                            log.debug("平均分配的组内坐席 stafflist2:" + stafflist2);

                            int groupno = Integer.parseInt(resgroups.get(c).get(1).toString());
                            //将每组的任务量平均分配给组内坐席
                            groupresUsers = AllotUtil.getAllotNum(stafflist2, groupno, "平均");
                            log.debug("将每组的任务量平均分配给组内坐席groupresUsers:" + groupresUsers);
                            for (List<String> groupresUser : groupresUsers) {
                                groupresUser.add("0");
                            }
                            //合并所有组别内的坐席
                            for (List<String> groupresUser : groupresUsers) {
                                resUsers.add(groupresUser);
                            }
                        }
                        log.debug("resUsers_rolegroup:" + resUsers);
                    }

                    log.debug("resUsers:" + resUsers + " resUsers-size:" + resUsers.size());

                    //根据 resUsers 集合将任务分配给每个坐席
                    int j = 0;
                    for (int i = 0; i < issue_usernoi && resUsers.size() > 0; i++) {
                        log.debug("当前处理坐席序号:" + j + "； resUsers.get(j)集合：" + resUsers.get(j) + "； i是：" + i + "； resUsers.size()：" + resUsers.size());
                        String staffid = resUsers.get(j).get(0).toString();//坐席id
                        int staffTaskNO = Integer.parseInt(resUsers.get(j).get(1));//坐席的任务量
                        int staffIssueNO = Integer.parseInt(resUsers.get(j).get(2));//坐席已分配到任务量

                        if (staffIssueNO < staffTaskNO) {
                            //调用分配方法
                            int reFlag = assignTasks(eliteBean, rule_id, staffid, issue_range, where_sql, order_sql);
                            log.debug("reFlag:" + reFlag);
                            if (reFlag==1) {
                                staffIssueNO++;
                                resUsers.get(j).set(2, String.valueOf(staffIssueNO));
                                dealcont = resUsers.get(j).get(0) + "应分配：" + resUsers.get(j).get(1) + "，实际分配到：" + resUsers.get(j).get(2);
                                j++;
                            } else if(reFlag==0){
                                dealcont = resUsers.get(j).get(0).toString() + "应分配：" + String.valueOf(staffTaskNO) + "，实际分配到：" + String.valueOf(staffIssueNO) + "，规则筛选出的任务量不足；";
                                resUsers.get(j).set(2, String.valueOf(staffTaskNO));
                                //将分配失败的坐席移除集合
                                resUsers.remove(j);
                            }else{
                                i--;
                                j++;
                            }
                            assignMap.put(staffid, dealcont);

                        } else {
                            dealcont = resUsers.get(j).get(0) + "应分配：" + String.valueOf(staffTaskNO) + "，实际分配到：" + String.valueOf(staffIssueNO) + "；";
                            assignMap.put(staffid, dealcont);
                            log.debug("dealcont实际分配到:" + dealcont);
                            //将分配到的任务量等于应分配的任务量的坐席移出集合
                            resUsers.remove(j);
                        }
                        //回到集合原点
                        if (j == resUsers.size()) {
                            j = 0;
                        }
                    }
                }

                //记录规则执行情况
                String insertdealcontSQL = "INSERT INTO hst_reuser_rule_deallist (DEAL_GUID, RULE_ID, DEALCONT, CREATEDBY, CREATEDDATE) VALUES (UUID(),'" + rule_id + "','" + assignMap.toString() + "', 'SELITE', now())"
                int insertdealcontNum = eliteBean.update(insertdealcontSQL, "dataSource");
                log.debug("规则执行情况 assignMap:" + assignMap.toString() + " DB Result:" + insertdealcontNum);

                //更新规则上次执行时间
                String updateSQL = "UPDATE hst_reuser_rule_issue SET LAST_DATE = now() WHERE rule_id = '" + rule_id + "'"
                int updateSQLNum = eliteBean.update(updateSQL, "dataSource");
                log.debug("更新规则上次执行时间 rule_id:" + rule_id + " DB Result:" + updateSQLNum);

            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
    }

    //分配任务，1：成功返回、0：失败返回、-1：接口返回失败；
    public static int assignTasks(EliteBean eliteBean, String rule_id, String staffid, String issue_range, String where_sql, String order_sql) {
        int reFlag = 0;
        def groupid = "";
        def counselor_id = "";//服务顾问id

        List groupidlist = eliteBean.chaxun_sql("SELECT DEFAULTROLEGROUP, counselor_id FROM staff WHERE staff_id = '" + staffid + "' ", "dataSource");
        if (groupidlist.size() > 0) {
            groupid = groupidlist.get(0).get("DEFAULTROLEGROUP");
            counselor_id = groupidlist.get(0).get("counselor_id");
        }
        issue_range = issue_range.replace(",", "' , '");
        log.debug("issue_range:" + issue_range);

        List objectivelist = eliteBean.chaxun_sql("SELECT o.objective_guid, o.customer_guid, o.handleby_id, o.handlegroup_id, o.distributionnumber, customer.customer_id FROM objective o LEFT JOIN assign_his_Follow_up_person a ON o.objective_guid = a.objective_guid LEFT JOIN customer ON customer.customer_guid = o.customer_guid LEFT JOIN hst_recycle_check h ON h.advisory_batchid = o.CUSTLISTNAME LEFT JOIN elitetask_activity ON elitetask_activity.objective_guid = o.objective_guid WHERE 1=1 AND o.MAP_ID = 'MY48ZX' AND o.recycledate IS NOT NULL AND o.retaindeadline < now() AND a.HANDLEBY_ID <> '" + staffid + "' AND h.recovery_guid IN ('" + issue_range + "') " + where_sql + " group by o.objective_guid, o.customer_guid, o.handleby_id, o.handlegroup_id, o.distributionnumber, customer.customer_id " + order_sql + " LIMIT 1", "dataSource");
        log.debug("objectivelist:" + objectivelist + "; objectivelist.size():" + objectivelist.size());

        if (objectivelist.size() > 0) {
            def objective_guid = objectivelist.get(0).get("objective_guid");
            //分配累计数
            String DISTRIBUTION_NUMBER_STR = objectivelist.get(0).get("DISTRIBUTIONNUMBER");
            Integer DISTRIBUTION_NUMBER = 1;
            if(DISTRIBUTION_NUMBER_STR == null || DISTRIBUTION_NUMBER_STR == 0 ){
                DISTRIBUTION_NUMBER = 1;
            }else{
                DISTRIBUTION_NUMBER = Integer.parseInt(DISTRIBUTION_NUMBER_STR);
            }
            //拼接报文，调用'华盛服顾绑定'接口
            try {
                //华盛接口连续调用可能异常 添加1S睡眠
                Thread.sleep(1 * 1000);
                String injson = "{\"hsNo\":\"" + objectivelist.get(0).get("customer_id") + "\", \"managerId\":\"" + counselor_id + "\", \"divideType\":\"0\", \"divideNumber\":\""+ objectivelist.get(0).get("distributionnumber") +"\"}";
                String sysurl = KHDBConfig.getAPIURL(eliteBean, "API-InnerDomain");//配置本地接口地址
                String doURL = sysurl + "/aipHSTBindCounselor";
                Map<String, String> headMap = new HashMap<String, String>();
                headMap.put("Content-Type", "application/x-www-form-urlencoded");
                def getResult = Util.doHttpPostUseHead(doURL, injson, "UTF-8", 10000, 0, headMap);
                log.debug("华盛服顾绑定接口返回-getResult:" + getResult);
                JSONObject jsonObject = new JSONObject(getResult);
                String code = KHUtil.GetJV(jsonObject, "result");

                if (code == "1") { //接口返回成功,则更新数据表
                    String[] data = new String[3];
                    data[0] = "UPDATE objective SET HANDLEBY_ID='" + staffid + "', HANDLEGROUP_ID='" + groupid + "', recycledate = NULL, retaindeadline = NULL, distributiontime = now(), distributionnumber = distributionnumber+1, objectivesubstatus='', contact_cause = null WHERE 1=1 AND objective_guid = '" + objective_guid + "'";
                    data[1] = "UPDATE elitetask SET HANDLEBY_ID='" + staffid + "', HANDLEGROUP_ID='" + groupid + "', createddate = NOW(), objectivesubstatus='', MODIFIEDDATE=null where 1=1 AND objective_guid = '" + objective_guid + "'";
                    data[2] = "INSERT INTO Assign_His (Assign_Guid, Customer_Guid, Objective_Guid, Oldhandlegroup_Id, Oldhandleby_Id, Newhandlegroup_Id, Newhandleby_Id, Assigngroup_Id, Assignby_Id, Assigndate, recovery_guid, Success_Guid) VALUES (Uuid(), '" + objectivelist.get(0).get("customer_guid") + "', '" + objective_guid + "', '" + objectivelist.get(0).get("handlegroup_id") + "', '" + objectivelist.get(0).get("handleby_id") + "', '" + groupid + "', '" + staffid + "', 'SYSTEM', 'SELITE', Now(), '" + rule_id + "', '回收规则再分配' )";
                    int[] dataresult = eliteBean.updateBatch(data, "dataSource");
                    log.debug("dataresult:" + dataresult);
                    reFlag = 1;
                } else {
                    reFlag = -1;
                }

            } catch (Exception e) {
                log.error(e.getMessage(), e);
                reFlag = -1;
            }

        } else {
            reFlag = 0;
        }
        return reFlag;
    }
}
